1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
| #include <cstdio> #include <queue> #include <cstring> #include <algorithm> const int maxn = 2005; const int S = 0; const int T = 2001; const int INF = 0x3f3f3f3f; using namespace std; struct E{ int to, nxt, f; }e[maxn << 4]; int now[maxn], head[maxn], tot = 1; void addedge(int u, int v, int f){ e[++tot].to = v, e[tot].nxt = head[u], e[tot].f = f; head[u] = tot; } void ins(int u, int v, int f){ addedge(u, v, f); addedge(v, u, 0); } int dep[maxn]; bool bfs(){ queue <int> q; while (!q.empty()) q.pop(); q.push(S); memset(dep, 0, sizeof dep); dep[S] = 1; while (!q.empty()){ int cur = q.front(); q.pop(); for (int i = head[cur]; i; i = e[i].nxt){ int v = e[i].to; if (dep[v] == 0 && e[i].f > 0){ dep[v] = dep[cur] + 1; q.push(v); } } } return dep[T] > 0; } int dfs(int cur, int Max){ if (cur == T) return Max; int flow = 0; for (int i = head[cur]; i; i = e[i].nxt){ int v = e[i].to; if (e[i].f > 0 && dep[v] == dep[cur] + 1){ int tmp = dfs(v, min(Max - flow, e[i].f)); flow += tmp; e[i].f -= tmp; e[i ^ 1].f += tmp; if (flow == Max) return flow; } } return flow; } int maxflow; void Dinic(){ maxflow = 0; while (bfs()) maxflow += dfs(S, INF); } int n, m, u[maxn], v[maxn], a[maxn], b[maxn]; int Min = INF, Max = 0, dex[maxn], last[maxn]; bool check(int mid){ memset(dex, 0, sizeof dex); tot = 1; memset(head, 0, sizeof head); for (int i = 1; i <= m; i++){ if (a[i] > mid && b[i] > mid) return false; if (a[i] <= mid) dex[u[i]]--, dex[v[i]]++; if (b[i] <= mid) ins(v[i], u[i], 1), last[i] = tot - 1; else last[i] = 0; } int sum = 0; for (int i = 1; i <= n; i++){ if (dex[i] & 1) return false; if (dex[i] > 0) ins(S, i, dex[i] >> 1), sum += dex[i]; else ins(i, T, (-dex[i]) >> 1); } Dinic(); return maxflow == (sum >> 1); } namespace SPJ{ struct E{ int to, nxt; }e[::maxn << 1]; int head[maxn], dex[maxn], tot = 0; void addedge(int u, int v){ e[++tot].to = v, e[tot].nxt = head[u]; head[u] = tot; ++dex[u]; ++dex[v]; } bool vis[maxn]; deque <pair<int, int> > v[maxn], t[maxn]; void dfs(int cur){ if (dex[cur] == 0) return; dex[cur]--; for (int i = head[cur]; i; i = e[i].nxt){ if (!vis[i]){ vis[i] = 1; t[cur].push_back(make_pair(i,e[i].to)); dex[e[i].to]--; dfs(e[i].to); break; } } } void solve(){ for (int i = 1; i <= ::n; i++){ if (dex[i] != 0) dfs(i); for (int j = 1; j <= n; j++) while (!t[j].empty()){
v[j].push_front(t[j].back()), t[j].pop_back(); } } int cur = 1; while (!v[cur].empty()){ printf("%d ", v[cur].front().first); int tmp = v[cur].front().second; v[cur].pop_front(); cur = tmp; } puts(""); } } int main(){ scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++){ scanf("%d%d%d%d", u + i, v + i, a + i, b + i); Min = min(Min, min(a[i], b[i])); Max = max(Max, max(a[i], b[i])); if (a[i] > b[i]) swap(u[i], v[i]), swap(a[i], b[i]); } int l = Min, r = Max, ans = -1; while (l <= r){ int mid = l + r >> 1; if (check(mid)){ ans = mid, r = mid - 1; memset(SPJ::head, 0, sizeof SPJ::head); SPJ::tot = 0; memset(SPJ::dex, 0, sizeof SPJ::dex); for (int i = 1; i <= m; i++) if (last[i] != 0 && e[last[i]].f == 0) SPJ::addedge(v[i], u[i]); else SPJ::addedge(u[i], v[i]); } else l = mid + 1; } if (ans == -1) puts("NIE"); else printf("%d\n", ans); if (ans != -1) SPJ::solve(); return 0; }
|